package cn.ococci.dm.Main.Tools;

import android.content.Context;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;

import org.apache.commons.codec.binary.Hex;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import cn.ococci.dm.Base.BaseApp;
import cn.ococci.dm.Main.Const;
import cn.ococci.dm.Main.Model.Ota;
import cn.ococci.dm.Main.OtaType;


/**
 * 文件操作工具类
 */
public class FileTool {


	private static final File filePath =  Environment.getExternalStorageDirectory();



	/**
	 * 删除空目录
	 * @param dir 将要删除的目录路径
	 */
	private static void doDeleteEmptyDir(String dir) {
		boolean success = (new File(dir)).delete();
		if (success) {
			System.out.println("Successfully deleted empty directory: " + dir);
		} else {
			System.out.println("Failed to delete empty directory: " + dir);
		}
	}

	/**
	 * 递归删除目录下的所有文件及子目录下所有文件
	 * @param dir 将要删除的文件目录
	 * @return
	 */
	private static boolean deleteDir(File dir) {
		if (dir.isDirectory()) {
			String[] children = dir.list();
			//递归删除目录中的子目录下
			for (int i=0; i<children.length; i++) {
				boolean success = deleteDir(new File(dir, children[i]));
				if (!success) {
					return false;
				}
			}
		}
		// 目录此时为空，可以删除
		return dir.delete();
	}


	public static void deleteDirectory(){

		String path = filePath + "/Download/.um/";
		File file = new File(path);

		LogTool.log(LogTool.CYAN,"path:" + path);
		if (file.exists()){

			LogTool.log(LogTool.CYAN,"删除"+(deleteDir(file)?"成功":"失败"));

		}

	}


    public static void writerStringToFile(String str, String filename) {
        File file = new File(filename);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(str.getBytes());
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void appendStringToFile(String fileName, String content) {
        try {
            //打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件
            FileWriter writer = new FileWriter(fileName, true);
            writer.write(content);
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

	public static String getDiskCacheDir() {
		String cachePath;
		Context context= BaseApp.getInstance();
		if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
				|| !Environment.isExternalStorageRemovable()) {
			cachePath = context.getExternalCacheDir().getPath();
		} else {
			cachePath = context.getCacheDir().getPath();
		}
		return cachePath;
	}

    public static String getStringFromFile(String filename) {
        return getStringFromFile(new File(filename));
    }

    public static String getStringFromFile(File file) {
        try {
            if (!file.exists() || !file.canRead())
                return null;
            BufferedReader br = new BufferedReader(new FileReader(file));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            br.close();
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    public static String getAppFileDir() {
        return BaseApp.getInstance().getFilesDir().toString() + "/";
    }


	/**
	 * 获取固件的文件路径
	 * @return
     */
	public static  String getOtaPath(){
		return   BaseApp.getInstance().getFilesDir().toString() + "/"+Const.OTA_Directory;
	}



	/**
	 * 复制单个文件
	 * 
	 * @return boolean
	 */
	public static int copyFile(File src, File dest) {
		try {
			int byteSum = 0;
			int byteRead;

			if (src.exists()) { // 文件存在时
				InputStream inStream = new FileInputStream(src); // 读入原文件
				if(!dest.exists()){
					dest.createNewFile();
				}
				FileOutputStream fs = new FileOutputStream(dest);
				byte[] buffer = new byte[1444];
				while ((byteRead = inStream.read(buffer)) != -1) {
					byteSum += byteRead; // 字节数 文件大小
					fs.write(buffer, 0, byteRead);
				}
				inStream.close();
				fs.close();
			}
			return byteSum;
		} catch (Exception e) {

			System.out.println("复制单个文件操作出错");
			e.printStackTrace();
			return 0;
		}
	}




	static class CustomComparator implements Comparator<File> {

		@Override
		public int compare(File f1, File f2) {
			/*
			 * 1.先比较文件夹 （文件夹在文件的顺序之上）2.以A-Z的字典排序3.比较文件夹和文件4.比较文件和文件夹
			 */
			if (f1.isDirectory() && f2.isDirectory()) {
				return f1.getName().compareToIgnoreCase(f2.getName());
			} else {

				if (f1.isDirectory() && f2.isFile()) {
					return -1;
				} else if (f1.isFile() && f2.isDirectory()) {
					return 1;
				} else {
					return f1.getName().compareToIgnoreCase(f2.getName());
				}
			}
		}
	}



	/**
	 * 复制文件
	 * 
	 * @param srcFile
	 *            源文件
	 * @param destFile
	 *            目标文件
	 * @throws IOException
	 */
	public static void cpFile(File srcFile, File destFile) {
		FileInputStream in = null;
		FileOutputStream out = null;
		try {
			in = new FileInputStream(srcFile);
		    out = new FileOutputStream(destFile);

			byte[] buf = new byte[1024 * 16];
			int len;
			while (-1 != (len = in.read(buf))) {
				out.write(buf, 0, len);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				if(out != null) {
					out.flush();
					out.close();
				}
				if(in != null)
					in.close();

			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
		

	}

	/**
	 * 重命名
	 * 
	 * @param file
	 *            当前文件
	 * @param newPath
	 *            新的文件
	 * @return 是否成功
	 */
	public static boolean rename(File file, File newPath) {
		if (!newPath.exists()) {
			return file.renameTo(newPath);
		} else {
			return false;
		}
	}

	public static double getAutoFileOrFilesSize(String filePath) {
		File file = new File(filePath);
		long blockSize = 0;
		try {
			blockSize = getFileSize(file);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return blockSize;

	}

	/**
	 * 获取指定文件大小
	 * 
	 * @param file
	 * @return
	 * @throws Exception
	 */
	private static long getFileSize(File file) throws Exception {
		long size = 0;
		if (file.exists()) {
			FileInputStream fis;
			fis = new FileInputStream(file);
			size = fis.available();
		} else {
			file.createNewFile();
			Log.e("获取文件大小", "文件不存在!");
		}
		return size;
	}


	/**
	 * File
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public static String fileToBase64WithString(File file) {
		FileInputStream inputFile;
		byte[] buffer = null;
		try {
			inputFile = new FileInputStream(file);
			buffer = new byte[(int)file.length()];
			inputFile.read(buffer);
			inputFile.close();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			return Base64.encodeToString(buffer,Base64.DEFAULT);
		}

	}


	/**
	 *
	 * @param base64Code
	 * @param savePath
	 * @throws Exception
	 */
	public static void base64ToFile(String base64Code,String savePath){
		byte[] buffer =Base64.decode(base64Code, Base64.DEFAULT);
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(savePath);
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				out.write(buffer);
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}


	/**
	 * 创建OTA文件目录
	 */
	public static void createOTADirectory(){
		final String dir = FileTool.getAppFileDir() + Const.OTA_Directory;

		File file = new File(dir);

		if (!file.exists()){
			file.mkdirs();
		}
	}


	// 删除文件
	public static void deleteFile(String path){

		File file = new File(path);
		if (file.exists()){
			file.delete();
		}
	}



	/**
	 * 对一个文件获取md5值
	 * @return md5串
	 */
	public static String getMD5(File file){

		 MessageDigest MD5 = null;

		try {
			MD5 = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException ne) {
			ne.printStackTrace();
		}

		FileInputStream fileInputStream = null;
		try {
			fileInputStream = new FileInputStream(file);
			byte[] buffer = new byte[8192];
			int length;
			while ((length = fileInputStream.read(buffer)) != -1) {
				MD5.update(buffer, 0, length);
			}

			return new String(Hex.encodeHex(MD5.digest()));

		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				if (fileInputStream != null)
					fileInputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}




}


